Docker 环境下 MySQL 远程连接问题排查指南

问题描述

在 Docker 容器中运行的 MySQL 数据库,虽然容器内 MySQL 运行正常,并且已经映射了 3306 端口到主机,但是无论是本机还是外网都无法连接到 MySQL 服务。

问题分析

这是一个典型的 Docker 网络访问权限问题。错误日志显示来自 Docker 默认网桥 IP(172.17.0.1)的访问被拒绝,这表明 MySQL 的用户权限配置可能存在问题。

解决步骤

1. 重置 MySQL 用户权限

首先进入 MySQL 容器并重置用户权限:

# 进入 MySQL 容器
docker exec -it your_mysql_container bash

# 连接 MySQL
mysql -u root -p

# 检查当前用户权限
SELECT user, host FROM mysql.user;

# 删除现有的 root 用户设置
DROP USER 'root'@'%';
DROP USER 'root'@'localhost';
DROP USER 'root'@'172.17.0.1';

# 重新创建 root 用户并授权
CREATE USER 'root'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

2. 检查 MySQL 配置

确保 MySQL 配置允许远程连接:

# 在容器内执行
cat /etc/mysql/my.cnf
# 或
cat /etc/mysql/mysql.conf.d/mysqld.cnf

如果看到 bind-address = 127.0.0.1​,需要修改为:

bind-address = 0.0.0.0

3. 重启容器

docker restart your_mysql_container

4. 验证连接

# 从主机测试连接
mysql -h localhost -u root -p

# 从远程测试连接
mysql -h your_server_ip -u root -p

故障排查清单

如果还是无法连接,请检查以下几点:

1. 检查 Docker 端口映射

docker inspect your_mysql_container | grep -A 20 PortBindings

确保看到类似输出:

"PortBindings": {
    "3306/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "3306"
        }
    ]
}

2. 检查防火墙设置

sudo ufw status

确保 3306 端口已开放:

sudo ufw allow 3306

注意事项

  1. 为了安全考虑,建议不要使用 root 用户进行远程连接
  2. 建议限制特定 IP 地址的访问权限,而不是使用 '%'
  3. 在生产环境中,应该使用更强的密码策略
  4. 考虑使用 SSL/TLS 加密连接

总结

MySQL 远程连接问题通常涉及多个层面:用户权限、网络配置、防火墙设置等。通过系统的排查和配置,可以逐步定位和解决问题。在解决问题的同时,也要注意保持系统的安全性。